package JUC.pc;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 对于监视器所进行的的一个调度线程的规定的顺序操作
 * A执行完调用B，B执行完调用C，C执行完调用A
 */
public class C {
    public static void main(String[] args) {
        Date3 date3 = new Date3();

        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                date3.printA();
            }

        },"A").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                date3.printB();
            }

        },"B").start();
        new Thread(()->{
            for (int i = 0; i <10 ; i++) {
                date3.printC();
            }

        },"C").start();
    }
}

//资源类
class Date3{
    private Lock lock=new ReentrantLock();//lock锁
    Condition condition1 = lock.newCondition();//同步监视器
    Condition condition2 = lock.newCondition();//同步监视器
    Condition condition3 = lock.newCondition();//同步监视器
    private int number =1;//1A 2B 3C

    public void printA(){
        //加锁
         lock.lock();
        try {
           //业务代码 判断->执行->通知
            while(number!=1){
                //监视器1等待
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>AAAAAAAA");
            //精准唤醒，唤醒指定的人，B
            number =2;
            condition2.signal();//通知指定的监视器2
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
        lock.unlock();
        }

    }

    public void printB(){
        //加锁
        lock.lock();
        try {
            //业务代码 判断->执行->通知
            while(number!=2){
                //监视器2等待
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>BBBBBBB");
            //精准唤醒，唤醒指定的人，C
            number =3;
            condition3.signal();//通知指定的监视器3
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    public void printC(){
        //加锁
        lock.lock();
        try {
            //业务代码 判断->执行->通知
            while(number!=3){
                //监视器2等待
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName()+"=>CCCCCCC");
            //精准唤醒，唤醒指定的人，A
            number =1;
            condition1.signal();//通知指定的监视器3
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    //生产线：下单->支付->交易
}